/*
 * @Author: 李天惊 uf_lee@163.com
 * @Date: 2025-04-12 22:01:34
 * @LastEditors: 李天惊 uf_lee@163.com
 * @LastEditTime: 2025-04-13 14:40:03
 * @FilePath: \leemvvm\lee-mvvm\src\core\reactivity\effect.ts
 * Copyright (c) 2025 by ${git_name_email}, All Rights Reserved.
 */

const effectStack: (() => void)[] = [];
// 定义一个全局变量，用于存储当前激活的副作用函数
let activeEffect: (() => void) | null = null;

// 创建一个副作用函数，并立即执行
export function effect(fn: () => void) {
  const wrappedEffect = () => {
    try {
      effectStack.push(fn);
      activeEffect = fn;
      fn();
    } finally {
      effectStack.pop();
      activeEffect = effectStack[effectStack.length - 1] || null;
    }
  };
  wrappedEffect();
  // // 设置当前激活的副作用函数为传入的函数
  // activeEffect = fn;
  // // 立即执行副作用函数
  // fn();
  // // 重置当前激活的副作用函数为null
  // activeEffect = null;
}

// 创建一个 WeakMap，用于存储对象和属性的依赖关系
const targetMap = new WeakMap<object, Map<string | symbol, Set<() => void>>>();

// 依赖收集函数
export function track(target: object, key: string | symbol) {
  // 如果当前没有激活的副作用函数，则直接返回
  if (!activeEffect) return;

  // 获取当前对象的依赖关系
  let depsMap = targetMap.get(target);
  // 如果当前对象没有依赖关系，则创建一个空的依赖关系
  if (!depsMap) {
    // 如果当前对象没有依赖关系，则创建一个空的依赖关系
    depsMap = new Map();
    // 将当前对象和依赖关系存储到 WeakMap 中
    targetMap.set(target, depsMap);
  }
  // 获取当前属性的依赖关系
  let deps = depsMap.get(key);
  // 如果当前属性没有依赖关系，则创建一个空的依赖关系
  if (!deps) {
    // 将当前属性和依赖关系存储到 Map 中
    deps = new Set();
    // 将当前属性和依赖关系存储到 Map 中
    depsMap.set(key, deps);
  }
  // 将当前激活的副作用函数添加到依赖关系中
  deps.add(activeEffect);
}

// 触发副作用函数
export function trigger(target: object, key: string | symbol) {
  // 获取当前对象的依赖关系
  const depsMap = targetMap.get(target);
  // 如果当前对象没有依赖关系，则直接返回
  if (!depsMap) return;
  // 获取当前属性的依赖关系
  const deps = depsMap.get(key);
  // 如果当前属性没有依赖关系，则直接返回
  if (!deps) return;
  // 遍历依赖关系，并执行对应的副作用函数
  deps.forEach((fn) => fn());
}
